package com.examsystem.listener;

import com.examsystem.util.JwtUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author fire'ge
 */
@Component
@WebListener
public class RequestListener implements ServletRequestListener {
    @Resource
    RedisTemplate<Object,Object> redisTemplate;

    Map<String,Integer> conditionMap= new HashMap<>();
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
    }

    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        HttpServletRequest servletRequest =(HttpServletRequest)sre.getServletRequest();
        String onlineUserIdStr = servletRequest.getHeader("onlineUserId");
        if (onlineUserIdStr==null){
            return;
        }
        int onlineUserId = Integer.parseInt(onlineUserIdStr);
        String token = servletRequest.getHeader("token");
        int jwtUserId = JwtUtil.getJWTUserId(token);
        if (jwtUserId==onlineUserId){
            conditionMap.put("userCode:"+jwtUserId,3);
        }
        ScheduledExecutorService service = new ScheduledThreadPoolExecutor(2);
        service.scheduleAtFixedRate(new RemoveUserOnline(jwtUserId), 0, 30000, TimeUnit.SECONDS);
        service.scheduleAtFixedRate(new DecrUserCode(jwtUserId), 0, 10000, TimeUnit.SECONDS);
    }
    class RemoveUserOnline implements Runnable
    {
        private final int userId;
        public RemoveUserOnline(int userId) {
            this.userId = userId;
        }

        @Override
        public void run() {
            Collection<Integer> values = conditionMap.values();
            for (int userCode:values) {
                if (userCode<=0){
                    redisTemplate.delete("login:user"+userId);
                }
            }
        }
    }

    class DecrUserCode implements Runnable
    {
        private final int userId;
        public DecrUserCode(int userId) {
            this.userId = userId;
        }

        @Override
        public void run() {
            Collection<Integer> values = conditionMap.values();
            for (int userCode:values) {
                conditionMap.put("userCode:"+userId,--userCode);
            }
        }
    }
}
